import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:dartssh2/dartssh2.dart';
import 'package:flutter_gbk2utf8/flutter_gbk2utf8.dart';
import 'package:hive_ce_flutter/hive_flutter.dart';
import 'package:uuid/uuid.dart';
import '../models/server_model.dart';

/// 服务器管理服务 - 全局单例，统一管理所有SSH连接
class ServerService {
  static const String _boxName = 'servers';
  static const String _groupBoxName = 'server_groups';
  late final Box<ServerModel> _box;
  late final Box<ServerGroup> _groupBox;
  static bool _isHiveInitialized = false;

  // SSH 连接池
  final Map<String, SSHClient> _clients = {};

  // 监控数据缓存
  final Map<String, ServerStatusData> _statusCache = {};

  // UUID 生成器
  final _uuid = const Uuid();

  // 🔔 服务器状态变化通知流 - 关键：实现全局状态同步
  final _serverStateController = StreamController<ServerModel>.broadcast();
  
  /// 监听服务器状态变化
  Stream<ServerModel> get serverStateStream => _serverStateController.stream;
  
  /// 监听特定服务器的状态变化
  Stream<ServerModel> watchServer(String serverId) {
    return _serverStateController.stream
        .where((server) => server.id == serverId);
  }

  /// 初始化
  Future<void> init() async {
    // 确保 Hive 只初始化一次
    if (!_isHiveInitialized) {
      await Hive.initFlutter();
      Hive.registerAdapter(ServerModelAdapter());
      Hive.registerAdapter(ServerStatusAdapter());
      Hive.registerAdapter(ServerGroupAdapter());
      _isHiveInitialized = true;
    }
    
    _box = await Hive.openBox<ServerModel>(_boxName);
    _groupBox = await Hive.openBox<ServerGroup>(_groupBoxName);
  }

  /// 添加服务器
  Future<ServerModel> addServer({
    required String name,
    required String host,
    required int port,
    required String username,
    String? password,
    String? privateKey,
    String? tags,
    String? groupId,
  }) async {
    final server = ServerModel(
      id: _uuid.v4(),
      name: name,
      host: host,
      port: port,
      username: username,
      password: password,
      privateKey: privateKey,
      createdAt: DateTime.now(),
      tags: tags,
      groupId: groupId,
    );

    await _box.put(server.id, server);
    // 🔔 通知新服务器添加
    _serverStateController.add(server);
    debugPrint('📢 ServerService: 广播新服务器添加 - ${server.name}');
    return server;
  }

  /// 获取所有服务器
  List<ServerModel> getAllServers() {
    return _box.values.toList();
  }

  /// 获取单个服务器
  ServerModel? getServer(String id) {
    return _box.get(id);
  }

  /// 更新服务器
  Future<void> updateServer(ServerModel server) async {
    await _box.put(server.id, server);
    // 🔔 通知状态变化
    _serverStateController.add(server);
    debugPrint('📢 ServerService: 广播服务器状态变化 - ${server.name}: ${server.status.displayName}');
  }

  /// 删除服务器
  Future<void> deleteServer(String id) async {
    // 断开连接
    await disconnectServer(id);
    // 删除数据
    await _box.delete(id);
    // 清除缓存
    _statusCache.remove(id);
  }

  /// 连接服务器
  Future<SSHClient> connectServer(String serverId) async {
    debugPrint('🔌 ServerService: 开始连接服务器 - ID: $serverId');
    
    final server = getServer(serverId);
    if (server == null) {
      debugPrint('❌ ServerService: 服务器不存在 - ID: $serverId');
      throw Exception('服务器不存在');
    }

    debugPrint('📋 ServerService: 服务器信息');
    debugPrint('   名称: ${server.name}');
    debugPrint('   地址: ${server.host}:${server.port}');
    debugPrint('   用户名: ${server.username}');
    debugPrint('   密码长度: ${server.password?.length ?? 0}');

    // 如果已连接，直接返回
    if (_clients.containsKey(serverId)) {
      debugPrint('✅ ServerService: 服务器已连接，返回现有连接');
      return _clients[serverId]!;
    }

    try {
      debugPrint('🔄 ServerService: 更新状态为连接中...');
      // 更新状态为连接中
      await updateServer(server.copyWith(status: ServerStatus.connecting));

      debugPrint('🌐 ServerService: 建立 TCP 连接 - ${server.host}:${server.port}');
      // 建立 TCP 连接
      final socket = await SSHSocket.connect(
        server.host,
        server.port,
        timeout: const Duration(seconds: 10),
      );
      debugPrint('✅ ServerService: TCP 连接成功');

      debugPrint('🔐 ServerService: 创建 SSH 客户端并进行认证...');
      debugPrint('   用户名: ${server.username}');
      debugPrint('   认证方式: 密码认证');
      
      // 创建 SSH 客户端
      final client = SSHClient(
        socket,
        username: server.username,
        onPasswordRequest: () {
          debugPrint('🔑 ServerService: 收到密码请求');
          final password = server.password ?? '';
          debugPrint('   返回密码长度: ${password.length}');
          return password;
        },
        // 主机密钥验证 - 关键修复：必须提供此回调
        onVerifyHostKey: (keyType, fingerprint) {
          final fingerprintHex = fingerprint
              .map((b) => b.toRadixString(16).padLeft(2, '0'))
              .join(':');
          debugPrint('🔐 ServerService: 验证主机密钥');
          debugPrint('   密钥类型: $keyType');
          debugPrint('   指纹: $fingerprintHex');
          // 生产环境应该验证指纹，这里为了兼容性总是接受
          // TODO: 实现完整的 known_hosts 管理
          return Future.value(true);
        },
        // 支持键盘交互式认证
        onUserInfoRequest: (userInfoRequest) {
          debugPrint('🔑 ServerService: 收到键盘交互式认证请求');
          debugPrint('   提示数量: ${userInfoRequest.prompts.length}');
          // 返回密码作为所有提示的答案
          final password = server.password ?? '';
          return List.filled(userInfoRequest.prompts.length, password);
        },
      );

      debugPrint('⏳ ServerService: 等待认证完成（最多30秒）...');
      // 等待认证完成
      await client.authenticated.timeout(
        const Duration(seconds: 30),
        onTimeout: () {
          debugPrint('⏰ ServerService: 认证超时！');
          throw TimeoutException('认证超时');
        },
      );
      debugPrint('✅ ServerService: SSH 认证成功！');

      // 保存连接
      _clients[serverId] = client;
      debugPrint('💾 ServerService: SSH 连接已保存到连接池');

      // 更新状态为已连接
      await updateServer(server.copyWith(
        status: ServerStatus.connected,
        lastConnectedAt: DateTime.now(),
      ));
      debugPrint('✅ ServerService: 服务器状态已更新为已连接');

      return client;
    } catch (e) {
      debugPrint('❌ ServerService: 连接失败 - 错误: $e');
      debugPrint('   错误类型: ${e.runtimeType}');
      
      // 更新状态为错误
      await updateServer(server.copyWith(status: ServerStatus.error));
      debugPrint('🔄 ServerService: 服务器状态已更新为错误');
      
      rethrow;
    }
  }

  /// 断开服务器连接
  Future<void> disconnectServer(String serverId) async {
    final client = _clients.remove(serverId);
    client?.close();

    final server = getServer(serverId);
    if (server != null) {
      await updateServer(server.copyWith(status: ServerStatus.disconnected));
    }
  }

  /// 获取服务器状态
  Future<ServerStatusData> getServerStatus(String serverId) async {
    final client = _clients[serverId];
    if (client == null) {
      return ServerStatusData.empty(serverId);
    }

    try {
      // 执行监控脚本
      final script = _generateMonitorScript();
      final result = await client.run(script);

      // 解码输出
      String output;
      try {
        output = utf8.decode(result, allowMalformed: true);
        // 如果有乱码，尝试 GBK
        if (output.contains('�')) {
          output = gbk.decode(result);
        }
      } catch (e) {
        output = gbk.decode(result);
      }

      // 解析监控数据
      final statusData = _parseMonitorOutput(serverId, output);
      _statusCache[serverId] = statusData;

      return statusData;
    } catch (e) {
      // 返回缓存或空数据
      return _statusCache[serverId] ?? ServerStatusData.empty(serverId);
    }
  }

  /// 获取缓存的状态数据
  ServerStatusData? getCachedStatus(String serverId) {
    return _statusCache[serverId];
  }

  /// 生成监控脚本（简化版）
  String _generateMonitorScript() {
    return '''
#!/bin/sh
# CPU
echo "CPU_INFO"
cat /proc/stat | grep "cpu " | head -1
# 内存
echo "MEM_INFO"
cat /proc/meminfo | grep -E "MemTotal|MemAvailable"
# 磁盘
echo "DISK_INFO"
df -k / | tail -1
# 网络
echo "NET_INFO"
cat /proc/net/dev | grep eth0
# 系统信息
echo "SYS_INFO"
cat /etc/*-release | grep PRETTY_NAME | head -1
hostname
uptime
''';
  }

  /// 解析监控输出（简化版）
  ServerStatusData _parseMonitorOutput(String serverId, String output) {
    final lines = output.split('\n');
    
    // 默认值
    double cpuUsage = 0;
    int totalMemory = 0;
    int availableMemory = 0;
    int totalDisk = 0;
    int usedDisk = 0;

    try {
      // 解析 CPU（简化）
      final cpuLine = lines.firstWhere(
        (line) => line.startsWith('cpu '),
        orElse: () => '',
      );
      if (cpuLine.isNotEmpty) {
        final parts = cpuLine.split(RegExp(r'\s+'));
        if (parts.length >= 5) {
          final user = int.tryParse(parts[1]) ?? 0;
          final system = int.tryParse(parts[3]) ?? 0;
          final idle = int.tryParse(parts[4]) ?? 0;
          final total = user + system + idle;
          if (total > 0) {
            cpuUsage = ((user + system) / total) * 100;
          }
        }
      }

      // 解析内存
      for (final line in lines) {
        if (line.contains('MemTotal:')) {
          final match = RegExp(r'(\d+)').firstMatch(line);
          if (match != null) {
            totalMemory = int.parse(match.group(1)!) * 1024; // KB to Bytes
          }
        } else if (line.contains('MemAvailable:')) {
          final match = RegExp(r'(\d+)').firstMatch(line);
          if (match != null) {
            availableMemory = int.parse(match.group(1)!) * 1024;
          }
        }
      }

      // 解析磁盘
      final diskLine = lines.firstWhere(
        (line) => line.contains('/') && !line.contains('Filesystem'),
        orElse: () => '',
      );
      if (diskLine.isNotEmpty) {
        final parts = diskLine.split(RegExp(r'\s+'));
        if (parts.length >= 4) {
          totalDisk = (int.tryParse(parts[1]) ?? 0) * 1024; // KB to Bytes
          usedDisk = (int.tryParse(parts[2]) ?? 0) * 1024;
        }
      }
    } catch (e) {
      // 解析失败，使用默认值
    }

    final usedMemory = totalMemory - availableMemory;
    final memoryUsage = totalMemory > 0 ? (usedMemory / totalMemory) * 100 : 0.0;
    final diskUsage = totalDisk > 0 ? (usedDisk / totalDisk) * 100 : 0.0;

    return ServerStatusData(
      serverId: serverId,
      timestamp: DateTime.now(),
      cpuUsage: cpuUsage,
      totalMemory: totalMemory,
      usedMemory: usedMemory,
      availableMemory: availableMemory,
      memoryUsage: memoryUsage.toDouble(),
      totalDisk: totalDisk,
      usedDisk: usedDisk,
      availableDisk: totalDisk - usedDisk,
      diskUsage: diskUsage.toDouble(),
      networkRxBytes: 0,
      networkTxBytes: 0,
      networkRxSpeed: 0,
      networkTxSpeed: 0,
    );
  }

  /// 获取服务器连接状态
  bool isConnected(String serverId) {
    return _clients.containsKey(serverId);
  }

  /// 获取 SSH 客户端（如果已连接）
  SSHClient? getClient(String serverId) {
    return _clients[serverId];
  }

  // ==================== 分组管理 ====================
  
  /// 创建服务器分组
  Future<ServerGroup> createGroup({
    required String name,
    String? description,
  }) async {
    final group = ServerGroup(
      id: _uuid.v4(),
      name: name,
      description: description,
      createdAt: DateTime.now(),
      sortOrder: _groupBox.length,
    );
    
    await _groupBox.put(group.id, group);
    debugPrint('✅ ServerService: 分组创建成功 - ${group.name}');
    return group;
  }
  
  /// 获取所有分组
  List<ServerGroup> getAllGroups() {
    final groups = _groupBox.values.toList();
    groups.sort((a, b) => a.sortOrder.compareTo(b.sortOrder));
    return groups;
  }
  
  /// 获取分组
  ServerGroup? getGroup(String groupId) {
    return _groupBox.get(groupId);
  }
  
  /// 更新分组
  Future<void> updateGroup(ServerGroup group) async {
    await _groupBox.put(group.id, group);
    debugPrint('✅ ServerService: 分组更新成功 - ${group.name}');
  }
  
  /// 删除分组
  Future<void> deleteGroup(String groupId) async {
    // 将该分组下的所有服务器的 groupId 设为 null
    final servers = getAllServers();
    for (final server in servers) {
      if (server.groupId == groupId) {
        final updatedServer = server.copyWith(groupId: null);
        await updateServer(updatedServer);
      }
    }
    
    await _groupBox.delete(groupId);
    debugPrint('✅ ServerService: 分组删除成功');
  }
  
  /// 根据分组获取服务器列表
  List<ServerModel> getServersByGroup(String? groupId) {
    return getAllServers()
        .where((server) => server.groupId == groupId)
        .toList();
  }
  
  /// 获取分组中的服务器数量
  int getServerCountInGroup(String? groupId) {
    return getServersByGroup(groupId).length;
  }
  
  /// 清理资源
  void dispose() {
    for (final client in _clients.values) {
      client.close();
    }
    _clients.clear();
    _statusCache.clear();
    _serverStateController.close();
  }
}

